package com.dzl.order.service.impl;

import com.dzl.config.exception.CommonException;
import com.dzl.constant.WelfareGoodsEnum;
import com.dzl.goods.pojo.WelfareGoods;
import com.dzl.goods.pojo.WelfareGoodsAttr;
import com.dzl.goods.service.WelfareGoodsAttrService;
import com.dzl.goods.service.WelfareGoodsService;
import com.dzl.order.pojo.WelfareOrder;
import com.dzl.order.pojo.WelfareOrderAddress;
import com.dzl.order.pojo.WelfareOrderGoods;
import com.dzl.order.pojo.WelfareOrderTempRemark;
import com.dzl.order.pojo.dto.WelfareOrderAddressDto;
import com.dzl.order.pojo.dto.WelfareOrderDto;
import com.dzl.order.pojo.dto.WelfareOrderGoodsDto;
import com.dzl.order.pojo.dto.WelfareOrderRemarkSupplierDto;
import com.dzl.order.service.*;
import com.dzl.order.utils.OrderUtils;
import com.dzl.shoppingCart.pojo.WelfareUserShoppingCart;
import com.dzl.shoppingCart.service.WelfareUserShoppingCartService;
import com.dzl.userwx.pojo.WelfareUserAddress;
import com.dzl.userwx.service.WelfareUserAddressService;
import com.dzl.util.EmptyUtils;
import com.dzl.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author ChenLong
 * @date 2021-08-06 14:32:23
 */
@Slf4j
@Service
public class OrderAddPhysicalServiceImpl implements OrderAddPhysicalService {

    @Autowired
    private WelfareUserAddressService welfareUserAddressService;
    @Autowired
    private WelfareOrderAddressService welfareOrderAddressService;
    @Autowired
    private WelfareOrderService welfareOrderService;
    @Autowired
    private WelfareOrderGoodsService welfareOrderGoodsService;
    @Autowired
    private WelfareGoodsAttrService welfareGoodsAttrService;
    @Autowired
    private WelfareUserShoppingCartService welfareUserShoppingCartService;
    @Autowired
    private WelfareGoodsService welfareGoodsService;
    @Autowired
    private WelfareOrderTempRemarkService welfareOrderTempRemarkService;

    @Override
    public Map<String, Object> addOrder(WelfareOrderDto orderDto) {
        Integer userId = orderDto.getUserId();
        Map<String, Object> resMap = new HashMap<>();
        // 订单地址校验，实体订单（普通实体、兑换实体订单）有地址，虚拟订单（普通虚拟、充值类虚拟订单）没有地址信息
        WelfareOrderAddressDto welfareOrderAddressDto = orderDto.getOrderAddress();
        if (EmptyUtils.isEmpty(welfareOrderAddressDto)) {
            throw new CommonException("请录入地址信息");
        }
        // 用户地址信息校验
        if (OrderUtils.validUserOrderAddress(welfareOrderAddressDto, resMap)) {
            return resMap;
        }

        // 插入地址信息到用户地址表，保存为默认地址(有则更新，无则插入)
        WelfareUserAddress welfareUserAddressSelect = new WelfareUserAddress();
        welfareUserAddressSelect.setUserId(userId);
        int count = welfareUserAddressService.selectCount(welfareUserAddressSelect);
        WelfareUserAddress welfareUserAddress = OrderUtils.buildUserAddressParams(welfareOrderAddressDto, userId);
        if (count > 0) {
            // 有记录就更新
            Example userAddressExample = new Example(WelfareUserAddress.class);
            // 更新用户地址
            userAddressExample.createCriteria().andEqualTo("userId", userId);
            welfareUserAddressService.updateByExampleSelective(welfareUserAddress, userAddressExample);
        } else {
            // 没有记录就插入用户地址
            welfareUserAddressService.insert(welfareUserAddress);
        }
        // 插入订单地址
        WelfareOrderAddress welfareOrderAddress = OrderUtils.buildUserOrderAddressParams(welfareOrderAddressDto);
        welfareOrderAddressService.insertSelective(welfareOrderAddress);
        Integer orderAddressId = welfareOrderAddress.getId();

        // 设置订单基本信息
        WelfareOrder welfareOrder = new WelfareOrder();
        OrderUtils.buildOrder(welfareOrder, orderDto);
        // 设置订单地址
        if (EmptyUtils.isNotEmpty(orderAddressId)) {
            welfareOrder.setAddressId(orderAddressId);
        }
        welfareOrderService.insertSelective(welfareOrder);
        int orderId = welfareOrder.getId();
        log.info("addUserOrder orderId: " + orderId);

        // 添加供应商维度的备注
        List<WelfareOrderRemarkSupplierDto> supplierRemarkList = orderDto.getSupplierRemarkList();
        if (EmptyUtils.isNotEmpty(supplierRemarkList) && supplierRemarkList.size() > 0) {
            List<WelfareOrderTempRemark> orderTempRemarkList = new ArrayList<>();
            for (WelfareOrderRemarkSupplierDto welfareOrderRemarkSupplierDto : supplierRemarkList) {
                WelfareOrderTempRemark welfareOrderTempRemark = new WelfareOrderTempRemark();
                welfareOrderTempRemark.setSupplierId(welfareOrderRemarkSupplierDto.getSupplierId());
                if (EmptyUtils.isNotEmpty(welfareOrderRemarkSupplierDto.getRemark())) {
                    welfareOrderTempRemark.setRemark(welfareOrderRemarkSupplierDto.getRemark());
                }
                welfareOrderTempRemark.setOrderId(orderId);
                welfareOrderTempRemark.setStatus(1);
                welfareOrderTempRemark.setCreateTime(new Date());
                orderTempRemarkList.add(welfareOrderTempRemark);
            }
            welfareOrderTempRemarkService.insertList(orderTempRemarkList);
        }

        List<WelfareGoodsAttr> welfareGoodsAttrList = new ArrayList<>();// 更新规格预占信息列表
        List<Integer> userCartIdList = new ArrayList<>();// 购物车Id列表
        BigDecimal totalOrderAmount = BigDecimal.ZERO;// 计算订单总金额
        List<WelfareOrderGoods> welfareOrderGoodsList = new ArrayList<>();// 订单商品表
        // 处理订单商品信息
        List<WelfareOrderGoodsDto> orderGoodsList = orderDto.getOrderGoodsList();
        for (WelfareOrderGoodsDto welfareOrderGoodsDto : orderGoodsList) {
            WelfareOrderGoods welfareOrderGoodsOpt = new WelfareOrderGoods();
            // 商品信息校验，设置订单商品信息
            WelfareGoods welfareGoods = welfareGoodsService.selectByPrimaryKey(welfareOrderGoodsDto.getGoodsId());
            if (EmptyUtils.isEmpty(welfareGoods)) {
                throw new CommonException("下单失败，无效的商品信息");
            }
            if (EmptyUtils.isNotEmpty(welfareGoods.getGoodsStatus()) && !welfareGoods.getGoodsStatus().equals(WelfareGoodsEnum.GOODS_STATUS_TYPE_SHELVES.getCode())) {
                throw new CommonException("下单失败，该商品已下架");
            }
            if (welfareGoods.getStatus() != null && welfareGoods.getStatus() == 0) {
                throw new CommonException("下单失败，商品失效");
            }
            if (EmptyUtils.isNotEmpty(welfareGoods.getGoodsImg())) {
                welfareOrderGoodsOpt.setGoodsImg(welfareGoods.getGoodsImg());
            }
            if (EmptyUtils.isNotEmpty(welfareGoods.getGoodsName())) {
                welfareOrderGoodsOpt.setGoodsName(welfareGoods.getGoodsName());
            }
            if (EmptyUtils.isNotEmpty(welfareGoods.getGoodsCode())) {
                welfareOrderGoodsOpt.setGoodsCode(welfareGoods.getGoodsCode());
            }
            welfareOrderGoodsOpt.setGoodsId(welfareOrderGoodsDto.getGoodsId());
            welfareOrderGoodsOpt.setGoodsType(welfareGoods.getGoodsType());
            welfareOrderGoodsOpt.setPartitionId(welfareGoods.getPartitionId());
            welfareOrderGoodsOpt.setSupplierId(welfareGoods.getSupplierId());
            // 规格信息校验，设置规格信息
            if (EmptyUtils.isEmpty(welfareOrderGoodsDto.getSkuId())) {
                throw new CommonException("下单失败，规格为空");
            }
            if (EmptyUtils.isEmpty(welfareOrderGoodsDto.getQuantity())) {
                throw new CommonException("下单失败，无效需求数量");
            }
            Integer reqQuantity = welfareOrderGoodsDto.getQuantity();// 需求数量
            Integer skuId = welfareOrderGoodsDto.getSkuId();
            WelfareGoodsAttr welfareGoodsAttr = welfareGoodsAttrService.selectByPrimaryKey(skuId);
            if (EmptyUtils.isEmpty(welfareGoodsAttr)) {
                throw new CommonException("下单失败，规格失效");
            }
            if (welfareGoodsAttr.getStatus() != null && welfareGoodsAttr.getStatus() == 0) {
                throw new CommonException("下单失败，该规格已失效");
            }
            //如果是导入商品，则根据平台商品的库存计算
            if(EmptyUtils.isNotEmpty(welfareGoodsAttr.getPlatformAttrId())){
                WelfareGoodsAttr welfareGoodsAttrPlatform = welfareGoodsAttrService.selectByPrimaryKey(welfareGoodsAttr.getPlatformAttrId());
                if(EmptyUtils.isNotEmpty(welfareGoodsAttrPlatform)){
                    welfareGoodsAttr.setQuantity(welfareGoodsAttrPlatform.getQuantity());
                    welfareGoodsAttr.setLockQuantity(welfareGoodsAttrPlatform.getLockQuantity());
                }
            }
            // 实体订单有预占和库存（虚拟充值类型订单没有）
            if (EmptyUtils.isEmpty(welfareGoodsAttr.getQuantity())) {
                throw new CommonException("下单失败，库存不足");
            }
            // 库存校验，如果库存不够
            if (welfareGoodsAttr.getQuantity() - welfareGoodsAttr.getLockQuantity() < reqQuantity) {
                throw new CommonException("下单失败，库存数量不足");
            }
            // 设置规格信息
            welfareOrderGoodsOpt.setSkuId(skuId);
            if (EmptyUtils.isNotEmpty(welfareGoodsAttr.getSkuPic())) {
                welfareOrderGoodsOpt.setSkuImg(welfareGoodsAttr.getSkuPic());
            }
            // 设置一级规格信息
            welfareOrderGoodsOpt.setFirstGroupId(welfareGoodsAttr.getFirstGroupId());
            welfareOrderGoodsOpt.setFirstGroupName(welfareGoodsAttr.getFirstGroupName());
            welfareOrderGoodsOpt.setFirstDetailId(welfareGoodsAttr.getFirstDetailId());
            welfareOrderGoodsOpt.setFirstDetailName(welfareGoodsAttr.getFirstDetailName());
            // 如果有二级规格，设置二级规格信息
            if (welfareGoodsAttr.getSecondGroupId() != null) {
                welfareOrderGoodsOpt.setSecondGroupId(welfareGoodsAttr.getSecondGroupId());
                welfareOrderGoodsOpt.setSecondGroupName(welfareGoodsAttr.getSecondGroupName());
                welfareOrderGoodsOpt.setSecondDetailId(welfareGoodsAttr.getSecondDetailId());
                welfareOrderGoodsOpt.setSecondDetailName(welfareGoodsAttr.getSecondDetailName());
            }
            // 如果有三级规格，设置三级规格信息
            if (welfareGoodsAttr.getThirdGroupId() != null) {
                welfareOrderGoodsOpt.setThirdGroupId(welfareGoodsAttr.getThirdGroupId());
                welfareOrderGoodsOpt.setThirdGroupName(welfareGoodsAttr.getThirdGroupName());
                welfareOrderGoodsOpt.setThirdDetailId(welfareGoodsAttr.getThirdDetailId());
                welfareOrderGoodsOpt.setThirdDetailName(welfareGoodsAttr.getThirdDetailName());
            }
            // 设置商品单价及数量
            welfareOrderGoodsOpt.setCreditsAmount(welfareGoodsAttr.getPrice());//设置商品规格价格（单件价格）
            welfareOrderGoodsOpt.setGoodsQuantity(reqQuantity);
            welfareOrderGoodsOpt.setCostPrice(welfareGoodsAttr.getCostPrice());//设置成本价格
            welfareOrderGoodsOpt.setCostTotalPrice(welfareGoodsAttr.getCostPrice().multiply(BigDecimal.valueOf(reqQuantity)));
            // 商品总价等于商品单价乘以数量
            BigDecimal goodsAmount = welfareGoodsAttr.getPrice().multiply(BigDecimal.valueOf(reqQuantity));
            totalOrderAmount = totalOrderAmount.add(goodsAmount);// 订单总价增加
            welfareOrderGoodsOpt.setOrderId(orderId);
            welfareOrderGoodsOpt.setCreateTime(new Date());
            welfareOrderGoodsOpt.setStatus(1);
            welfareOrderGoodsList.add(welfareOrderGoodsOpt);
            // 设置规格，预占数量加需求数量为新的预占数量（支付完以后释放预占，扣减库存）
            WelfareGoodsAttr welfareGoodsAttrOpt = new WelfareGoodsAttr();
            welfareGoodsAttrOpt.setId(skuId);
            // 实体类型订单有预占和库存（充值类型订单没有库存和预占）
            welfareGoodsAttrOpt.setLockQuantity(welfareGoodsAttr.getLockQuantity() + reqQuantity);
            welfareGoodsAttrOpt.setUpdateTime(new Date());
            welfareGoodsAttrOpt.setPlatformAttrId(welfareGoodsAttr.getPlatformAttrId());
            welfareGoodsAttrList.add(welfareGoodsAttrOpt);
            // 设置购物车记录为软删除（以购物车主键id方式）
            if (orderDto.getOrderWay().equals(1)) {
                if (EmptyUtils.isEmpty(welfareOrderGoodsDto.getCartId())) {
                    throw new CommonException("下单失败，购物车参数错误");
                }
                userCartIdList.add(welfareOrderGoodsDto.getCartId());
            }
        }
        // 插入记录到订单行表（订单商品表）
        welfareOrderGoodsService.insertList(welfareOrderGoodsList);
        // 更新订单总价
        WelfareOrder welfareOrderTotalAmount = new WelfareOrder();
        welfareOrderTotalAmount.setId(orderId);
        welfareOrderTotalAmount.setTotalAmount(totalOrderAmount);
        welfareOrderService.updateByPrimaryKeySelective(welfareOrderTotalAmount);

        // 如果是购物车下单方式，删除购物车商品
        if (orderDto.getOrderWay().equals(1) && EmptyUtils.isNotEmpty(userCartIdList) && userCartIdList.size() > 0) {
            Example userShoppingCartExample = new Example(WelfareUserShoppingCart.class);
            userShoppingCartExample.createCriteria().andIn("id", userCartIdList);
            welfareUserShoppingCartService.deleteByExample(userShoppingCartExample);
        }

        // 添加预占（存在并发修改同一条数据问题）
        if (EmptyUtils.isNotEmpty(welfareGoodsAttrList)) {
            for (WelfareGoodsAttr welfareGoodsAttr : welfareGoodsAttrList) {
                // 分布式Redis锁
                String key = RedisUtil.ORDER_RELEASE_LOCK_QUANTITY_PREFIX + welfareGoodsAttr.getId();
                RLock lock = RedisUtil.lock(key);
                try {
                    if (lock.tryLock()) {
                        welfareGoodsAttrService.updateByPrimaryKeySelective(welfareGoodsAttr);
                        //如果是导入商品，则修改平台商品的库存计算
                        if(EmptyUtils.isNotEmpty(welfareGoodsAttr.getPlatformAttrId())){
                            WelfareGoodsAttr welfareGoodsAttrPlatform = welfareGoodsAttrService.selectByPrimaryKey(welfareGoodsAttr.getPlatformAttrId());
                            if(EmptyUtils.isNotEmpty(welfareGoodsAttrPlatform)){
                                WelfareGoodsAttr welfareGoodsAttrPlatform_ = new WelfareGoodsAttr();
                                welfareGoodsAttrPlatform_.setId(welfareGoodsAttr.getPlatformAttrId());
                                welfareGoodsAttrPlatform_.setQuantity(welfareGoodsAttrPlatform.getQuantity());
                                welfareGoodsAttrPlatform_.setLockQuantity(welfareGoodsAttrPlatform.getLockQuantity());
                                welfareGoodsAttrService.updateByPrimaryKeySelective(welfareGoodsAttrPlatform_);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("addUserOrder e: " + e.getMessage(), e);
                    throw new CommonException(e.getMessage());
                } finally {
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }
            }
        }
        resMap.put("code", 1);
        resMap.put("orderId", orderId);
        resMap.put("msg", "success");
        return resMap;
    }
}
